package eredis

import (
	"context"
	"time"

	"git.edaijia-inc.cn/edaijia/ego/elogger"
	"git.edaijia-inc.cn/edaijia/ego/etracer"

	"github.com/go-redis/redis"
)

type ERedisConfig struct {
	Addr         string `ini:"addr"`
	DB           int    `ini:"db"`
	IdleTimeout  int    `init:"idleTimeout"` //闲置超时，默认5分钟，-1表示取消闲置超时检查
	MinIdleConns int    `ini:"minidleconns"` //在启动阶段创建指定数量的Idle连接，并长期维持idle状态的连接数不少于指定数量
	Passwd       string `ini:"passwd"`
	PoolSize     int    `ini:"poolsize"`     // 连接池最大socket连接数，默认为4倍CPU数， 4 * runtime.NumCPU
	DialTimeout  int    `ini:"dialtimeout"`  //连接建立超时时间，默认5秒。
	ReadTimeout  int    `ini:"readtimeout"`  //读超时，默认3秒， -1表示取消读超时
	WriteTimeout int    `ini:"writetimeout"` //写超时，默认等于读超时
	PoolTimeout  int    `ini:"pooltimeout"`  //当所有连接都处在繁忙状态时，客户端等待可用连接的最大等待时长，默认为读超时+1秒
}

type ERedis struct {
	Config *ERedisConfig
	client *redis.Client
}

func InitERedis(conf *ERedisConfig) *ERedis {
	client := redis.NewClient(&redis.Options{
		Network:      "tcp",
		Addr:         conf.Addr,
		Password:     conf.Passwd,
		DB:           conf.DB,
		PoolSize:     conf.PoolSize,
		DialTimeout:  time.Duration(conf.DialTimeout) * time.Second,
		ReadTimeout:  time.Duration(conf.ReadTimeout) * time.Second,
		WriteTimeout: time.Duration(conf.WriteTimeout) * time.Second,
		MinIdleConns: conf.MinIdleConns,
		PoolTimeout:  time.Duration(conf.PoolTimeout) * time.Second,
		IdleTimeout:  time.Duration(conf.IdleTimeout) * time.Minute,
	})
	_, err := client.Ping().Result()
	if err != nil {
		elogger.Error("redis OnConnect error", err)
	}
	return &ERedis{conf, client}
}

func (e *ERedis) Do(ctx context.Context, args ...interface{}) (result interface{}, err error) {
	etracer.ERedisSpanAround(
		ctx,
		e.Config.Addr,
		"Redis/EGO/GoRedis/Do",
		func() error {
			result, err = e.client.Do(args...).Result()
			if err != nil && err != redis.Nil {
				return err
			}

			return nil
		},
		args...,
	)

	return
}
